package com.specter.mvc.web;

import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.specter.sure.core.AuthContext;
import com.specter.utils.HttpUtils;

import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;

/**
 * Note:要求配置启用 SpecterSecurityFilter
 * 
 * @author Liang.Wang
 * 
 */
@Slf4j
public class WebContext extends WebConsts {
    // 添加显式构造函数调用父类私有构造函数
    public WebContext() {
        super();
    }
    
	// header 常量定义
	private static final String HEADER_ENCODING_PREFIX = "encoding";
	private static final String HEADER_ENCODING_DEFAULT = "UTF-8";
	private static final String HEADER_NOCACHE_PREFIX = "no-cache";
	private static final String HEADER_NOCACHE_DEFAULT = "true";

	public static HttpServletRequest getRequest() {
		return AuthContext.getRequest();
	}

	public static HttpServletResponse getResponse() {
		return AuthContext.getResponse();
	}

	public static HttpSession getSession() {
		return AuthContext.getSession();
	}

	public static ServletContext getContext() {
		return AuthContext.getServletContext();
	}

	/**
	 * 取得Request Parameter的简化方法.
	 */
	public static String getParameter(String name) {
		return getRequest().getParameter(name);
	}

	/**
	 * 直接返回整数类型的参数
	 * 
	 * @param name
	 * @param defaultValue
	 * @return
	 */
	public static Integer getIntParameter(String name, Integer defaultValue) {
		if (defaultValue == null) {
			throw new IllegalArgumentException("defaultValue must not null");
		}
		String value = getParameter(name);
		if (StringUtils.isBlank(value)) {
			return defaultValue;
		}
		return Integer.parseInt(value);
	}

	/**
	 * 取得所有参数
	 * 
	 * @return
	 */
	public static Map<String, ?> getParameters() {
		HttpServletRequest request = getRequest();
		Map<String, Object> retMap = new HashMap<>();
		Enumeration<String> e = request.getParameterNames();
		while (e.hasMoreElements()) {
			String name = e.nextElement();
			String[] values = request.getParameterValues(name);
			if (values == null || values.length == 0) {
				// Do nothing, no values found at all.
			} else if (values.length > 1) {
				retMap.put(name, values);
			} else {
				retMap.put(name, values[0]);
			}
		}

		return retMap;
	}

	// 绕过jsp/freemaker直接输出文本的函数 //

	/**
	 * 直接输出内容的简便函数.
	 * 
	 * <pre>
	 * eg.
	 * render("text/plain", "hello", "encoding:GBK");
	 * render("text/plain", "hello", "no-cache:false");
	 * render("text/plain", "hello", "encoding:GBK", "no-cache:false");
	 * </pre>
	 * 
	 * @see org.springframework.http.MediaType
	 * 
	 * @param headers 可变的header数组，目前接受的值为"encoding:"或"no-cache:",默认值分别为UTF-8和true.
	 */
	public static void render(final String contentType, final String content, final String... headers) {
		try {
			// 分析headers参数
			String encoding = HEADER_ENCODING_DEFAULT;
			boolean noCache = Boolean.parseBoolean(HEADER_NOCACHE_DEFAULT);
			for (String header : headers) {
				String headerName = StringUtils.substringBefore(header, ":");
				String headerValue = StringUtils.substringAfter(header, ":");

				if (StringUtils.equalsIgnoreCase(headerName, HEADER_ENCODING_PREFIX)) {
					encoding = headerValue;
				} else if (StringUtils.equalsIgnoreCase(headerName, HEADER_NOCACHE_PREFIX)) {
					noCache = Boolean.parseBoolean(headerValue);
				} else {
					throw new IllegalArgumentException(headerName + "is an illegal type!");
				}
			}

			HttpServletResponse response = getResponse();

			// 设置headers参数
			String fullContentType = contentType + ";charset=" + encoding;
			response.setContentType(fullContentType);
			if (noCache) {
				response.setHeader("Pragma", "No-cache");
				response.setHeader("Cache-Control", "no-cache");
				response.setDateHeader("Expires", 0);
			}

			response.getWriter().write(content);
			response.getWriter().flush();
			response.getWriter().close();
		} catch (IOException e) {
			log.error(e.getMessage(), e);
		}
	}

	public static void render(final String contentType, final String content) {
		render(contentType, content, HEADER_NOCACHE);
	}

	/**
	 * 导出下载文件
	 * 
	 * @param file 需导出的文件
	 */
	public static synchronized void exp(java.io.File file) {
		HttpUtils.exp(getResponse(), file);
	}

	public static <B> B getBean(String name, Class<B> clazz) {
		return WebApplicationContextUtils.getWebApplicationContext(getContext()).getBean(name, clazz);
	}

}